<?php
/**
 * Author: Traveler
 * Time  : 2021/9/4 19:17
 */

namespace app\service;


use app\ErrorCode;
use app\model\MenuModel;
use sunshine\basic\RestService;
use sunshine\exceptions\ApiException;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

class MenuService extends RestService
{
    /**
     * MenuService constructor.
     */
    public function __construct()
    {
        $this->model = new MenuModel();
        $this->initialize();
    }

    /**
     * 初始化
     */
    public function initialize()
    {
        $this->queryConditions['order'] = ['sort'];
    }

    /**
     * 获取列表(重写)
     *
     * @param array $search 搜索参数
     * @return array
     */
    public function select(array $search = []): array
    {
        // 列表转换为树形结构
        $this->isTreeResult = true;

        // 菜单列表不需要分页等操作，所以手动传入空数组
        return parent::select([]);
    }

    /**
     * 删除菜单(重写)
     *
     * @param int        $id 菜单id
     * @param array|null $relation
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function delete(int $id, ?array $relation = null): bool
    {
        // 检查是否存在下级菜单
        if ($this->getCountByParentId($id) > 0) {
            throw new ApiException(ErrorCode::HAS_CHILD_MENU);
        }

        return parent::delete($id);
    }

    /**
     * 获取所有菜单
     *
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getAllMenus(): array
    {
        return $this->model->order('sort')->select()->toArray();
    }

    /**
     * 根据父级id获取子菜单统计
     *
     * @param int  $parentId
     * @param bool $onlyMenu
     * @return int
     */
    public function getCountByParentId(int $parentId, bool $onlyMenu = true): int
    {
        $where = ['parent_id' => $parentId];
        if ($onlyMenu) {
            $where['type'] = 0;
        }

        return $this->getCountByWhere($where);
    }
}